/*
 * class name: cbo$,
 * copyright: maximus zhang,
 * License: MIT-LICENSE,
 * Date: 2008-06-06,
 * contact: maximus.zhang@gmail.com
 * -------
 * todo: ajax content, keys event, blur event, flitter user-typing
 */
function cbo$(){/* {name,id,elem,css,readonly,{opts}} */
    var A = arguments,
        _ = this;
    _ = ext$( _, ext$( {
            'name' : '',
            id : 'cbo'+ now$(3),
            elem : me.body,
            css : '',
            readonly : false,
            limit : true,
            opts:[]
            }, A[0] ) );
    _.uitype = 'cbo$';

    _.bound = false;
    _.on = false;

    _.valid$ = function(){
        if ( !_.opt || !_.opt.nodeName || (_._cbo.value=='' && (!_.readonly && _.cbo.value=='')) ) {
            return 'empty';
        }

        var x = attr$(_.opt, 'value');
        if ( _._cbo.value==_.opts[x].val && (!_.readonly && _.cbo.value==_.opts[x].txt) ) {
            return 'valid';
        }
    return false;
    };

    _.hide$ = function(click){
        if ( (_.bound && !_.on) || click===true ) {
            _.box.style.display = 'none';
            unbind$(me, 'mousedown', _.hide$);
            _.bound = false;
            _.on = false;
        }

        if ( !_.readonly && _.limit&&!_.valid$() ) {
            _.set$(-1);
        }

    return false;
    };

    _.show$ = function(){
        var pz = pos$(_.cbo),
            elem = _.elem;
        while ( elem.parentNode!=me.body ) {
            elem = elem.offsetParent;
        }

        var ppz = pos$(elem);//alert(pz.bottom +','+ elem.scrollTop);
        with ( _.box.style ) {
            top = pz.bottom-ppz.top+($$.opera?elem.scrollTop:0) +'px';
            left = pz.left +'px';
            display = 'block';
            zIndex = 9;
        }

        if ( _.opt && _.opt.nodeName=='A' ) {
            var st= attr$(_.opt,'value') ? attr$(_.opt,'value') : 0;
            _.box.scrollTop = st*20;
        }

        if ( !_.bound ) {
            bind$(me, 'mousedown', _.hide$);
            _.bound = true;
            _.on = true;
        }
    };

    _.togg$ = function(x){/* to be call or apply only!! */
        if ( isNaN(x) || x<0 || x>_.opts.length ) {
            return false;
        }

        if ( _.opt && _.opt.className=='a' ) {
            _.opt.className='';
        }

        delete _.opt;
        _.opt = this;
        _.opt.className = 'a';
        _.set$(x);
    };

    _.set$ = function(x){
        if ( isNaN(x) || x<0 || x>_.opts.length ) {
            if ( x==-1 ) {
                _._cbo.value = '';
                if ( _.readonly ) {
                    _.cbo.innerHTML='';
                } else {
                    _.cbo.value='';
                }

                if ( _.opt && _.opt.className=='a' ) {
                    _.opt.className='';
                }

                delete _.opt;

                return false;
            } else {
                return false;
            }
        }

        _._cbo.value = _.opts[x].val;

        if ( _.readonly ) {
            _.cbo.innerHTML = _.opts[x].txt;
        } else {
            _.cbo.value = _.opts[x].txt;
        }
    };

    _.add$ = function(el){
        var el = el || _.box;

        if ( !el ) {
            return false;
        }

        for ( var i = 0, L = _.opts.length; i<L; i++ ) {
            var opt = _.opts[i],
                x = el$('div').appendTo$(el);
            x.className = 'x';
            x.style.cssText = 'height:20px;line-height:20px;';

            var a = el$('a').appendTo$(x);
            a.style.cssText = 'padding-top:1px;padding-bottom:1px;';
            a.href = opt.val==undefined ? '#' : '#'+ opt.val;

            if ( opt.cls==='a' ) {
                a.className = 'a';
                _.set$(i);
                _.opt=a;
            }

            a.tabIndex = -1;
            attr$(a,'value',i);

            a.onclick = function(){
                if ( this.className=='a' ) {
                    return _.hide$(true);
                }

                _.togg$.apply(this, [attr$(this,'value')]);

            return _.hide$(true);
            };

            var t = el$('span').appendTo$(a);
            t.className = 't';
            var tx = el$(opt.txt, 1);
            t.appendChild(tx);
        }
    return true;
    };

    _.mouseover$ = function(){
        if ( _.bound ) {
            _.on = true;
        } else {
            _.on = false;
        }
    };

    _.mouseout$ = function(){
        if ( _.bound ) {
            _.on = false;
        }
    };

    _.init$ = function(){
        var div = el$('div').appendTo$(_.elem);
        div.style.width = _.elem.offsetWidth==0 ? '130px' : _.elem.offsetWidth +'px';
        div.style.cssText = p$(_,'css') ? _.css : '';

        var pz = pos$(div),
            L = _.opts.length;

        /* hidden input with name */
        _._cbo = el$('input');
        attr$(_._cbo, 'type', 'hidden');
        _._cbo.appendTo$(div);
        _._cbo.name = _.name;
        _._cbo.value = '';
        if ( _.readonly ) {
            _.cbo = el$('div').appendTo$(div);
            with ( _.cbo.style ) {
                border = 'solid 1px #ddd';
                backgroundColor = '#ffffef';
                height = '18px';
                width = pz.width-2 +'px';
            }
        } else {
            /* text input with id */
            _.cbo = el$('input');
            attr$(_.cbo, 'type', 'text');
            _.cbo.appendTo$(div);
            _.cbo.name = '';
            _.cbo.value = '';
            _.cbo.style.width = pz.width-4 +'px';
        }

        _.id = _.cbo.id = p$(_,'id') && !$(_.id) ? _.id : 'cbo'+ now$(3);

        _.cbo.onmouseover = _.mouseover$;
        _.cbo.onmouseout = _.mouseout$;
        _.cbo.onclick = function(){
            _.show$();
        };

        div.id = '_'+ _.id;
        _.box = el$('div').appendTo$(_.elem);
        _.box.tabIndex = -1;

        _.box.onmouseover = _.mouseover$;
        _.box.onmouseout = _.mouseout$;

        with ( _.box.style ) {
            cssText = 'border:solid 1px #bbb;display:none;overflow-y:auto;';
            left = pz.left +'px';
            top = pz.bottom +'px';
            height = L>11 ? '240px' : 20*L +'px';
            width = pz.width<60 ? '128px' : pz.width-2 +'px';
        }

        _.box.className = 'dm';
        _.add$(_.box);
    };
}
